programming4us
           
 
 
Windows Phone

Developing for Windows Phone and Xbox Live : Let the 3D Rendering Start

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
5/19/2011 4:43:06 PM
Now that we covered the basics of the graphics pipeline and some of the math that is involved, let’s see how these concepts relate to the types exposed by XNA Game Studio and draw some triangles on the screen.

GraphicsAdapter

Use the GraphicsAdapter class to enumerate and update graphics adapters. Most single monitor PCs have one graphics adapter that represents their physical graphics card and the one connection it has to the monitor. Some graphics cards provide two graphics adapters so you can plug two monitors into a single graphics card. In this case, the GraphicsAdapter allows for selecting two different adapters so you can display the graphics on two different monitors. The Xbox 360 and Windows Phone devices provide only one GraphicsAdapter.

The static GraphicsAdapter.DefaultAdapter property returns the default adapter in which there are multiple adapters to chose from. For example, when you set the left monitor to be the primary display in Windows, the DefaultAdapter property returns the GraphicsAdapter to display graphics on the left monitor.

The static GraphicsAdapter.Adapters property returns a read-only collection of the adapters available. You rarely need to enumerate graphics adapters. Most commercial PC games provide a settings page that enables the user to select the adapter so he or she can change which display to view the game. This is required when the game runs in full screen and the user does not have the normal window controls to click and drag.

If your game uses windowed mode, the user can click and draw the window to the other monitor. Although this changes the GraphicsAdapter used, all of this is handled for the user by XNA Game Studio by default.

Note

If you developed games using a native graphics API before and tried to support monitor dragging and toggling between windowed and full-screen modes, you know the trouble to get it working properly.


The GraphicsAdapter provides several properties and methods that enable you to determine what type of graphics card is available and what the capabilities of the graphics card are.

The QueryBackBufferFormat and QueryRenderTargetFormat methods can be used to determine whether a specific back buffer or render target format is supported.

The DeviceName, Description, DeviceId, VendorId, SubSystemId, and Revision properties are used to return information about a specific GraphicsAdapter to determine whether the graphics card is a specific model from a specific manufacturer. They also enable you to determine what the current driver version is.

Note

A graphics driver is a piece of software that enables the operating system to communicate with the graphics hardware. Graphics card manufacturers create the driver to instruct the operating system on how to perform specific tasks with the hardware.


Each GraphicsAdapter can support a number of display modes. Just as you can set your PC to use different resolutions, your game can use different resolutions. The SupportedDisplayModes returns a collection of DisplayMode structures. Each structure contains properties for the Width, Height, and Format for the display mode. A display format is defied using the SurfaceFormat enumeration. The format defines how each pixel on the screen is represented in terms of the data that is stored at each pixel. The most common format, SurfaceFormat.Color, is a 32-bit value that stores four channels of red, green, blue, and the alpha each with 8 bits of value.



The DisplayMode structure also provides two helper properties called AspectRatio and TitleSafeArea. The AspectRatio is the value you get when you divide the width of the display by the height of the display. This is often calculated when working with 3D graphics and is sometimes calculated incorrectly. The property gives you a simple way to retrieve the value without having to calculate the value each time you need it.

When drawing to televisions, they have outer edges of the screen cut off. If you draw to the top left corner of the screen and display this on a number of televisions, you will notice that each television has a slightly different position of where the top left corner is. The TitleSafeArea defines where you should limit drawing game specific graphics such as text and the heads up display for a character. Using the property ensures that your graphics are visible across different televisions.

GraphicsDevice

The GraphicsDevice in your game is responsible for issuing the drawing commands down to the driver, which then goes through the graphics pipeline. The GraphicsDevice is also responsible for loading graphics resources such as textures and shaders.

Every GraphicsDevice contains a back buffer. The back buffer is the data buffer where the graphics that ultimately end up displayed on your monitor are drawn to. It is called the back buffer because it is not displayed on the screen. What you see displayed on the screen is actually the contents of what is called the front buffer. Drawing occurs to the back buffer, so you don’t see each piece of geometry appear on the screen as it is drawn. After all of the draw calls are performed in a single frame, the GraphicsDevice.Present method is called, which flips the front and back buffers to display the contents of the back buffer.

Along with a width and height, the back buffer also has a SurfaceFormat, which defines the bit layout and use for each pixel in the back buffer. As we discussed, the GraphicsAdapter can be used to determine what formats are available. The most common is the Color format.

If a back buffer resolution that is smaller than the display is requested on the Xbox 360 or on a Windows Phone, the final image is up scaled to fit the screen. If the aspect ratio is different, then the display black bars are displayed on the top and bottom of the screen called letterboxing or on the sides of the screen called pillarboxing to fill out the extra space.

When calling the Present method, you specify a PresentInterval. The present interval is used to determine when the flip of the front and back buffers occur. Displays on computer monitors, televisions, and phone screens all have a refresh rate. The refresh rate is the speed that the displays update their physical screen commonly between 30Hrz to 60Hrz. When displays update, they do so by updating line by line until the entire screen is updated. At that time, the display performs a vertical retrace sometimes referred to as a vblank. This is when the screen is moving from the end of where it is currently updating to the start again. If the front and back buffers are flipped in the middle of the display, updating a graphical artifact called tearing can occur. Tearing is where part of the displayed screen shows one frame while another portion displays another. This occurs if the flip is not in sync with the vertical retrace because you change what is drawn on the screen in the middle of the display updating the display. To prevent this, the flip should occur during the vertical retrace.

When you set the PresentInterval, you have three options of when the flip between the front and back buffers occurs. If PresentInterval.One is used, the buffers wait to flip until the display is in the vertical retrace phase. This means the fastest your graphics can update is the same speed as your display’s refresh rate. PresentInterval.Two is used only to flip the buffers every other vertical retrace. PresentInterval.Immediate can be used to perform the flip as soon as possible and not wait for the vertical retrace. Although your game can suffer from tearing artifacts, this mode is helpful when performing performance analysis because it does not limit the speed at which your game can draw.

Along with the back buffer, a GraphicsDevice can also contain another buffer called the depth buffer. The depth buffer is used to store the depth values of a triangle when the color of that triangle is written to the back buffer. The values are used in the depth test position of the graphics pipeline that we discussed previously. A depth buffer can have three types of formats specified by the DepthFormat enumeration. The first is Depth16, which stores a 16-bit floating point value at each pixel. Depth24 provides a 24-bit floating point number to store depth at each pixel. Finally, the Depth24Stencil8 format provides the same 24 bits for depth but also enables another 8 bits to be used by the stencil buffer. The stencil buffer is used in the stencil test portion of the graphics pipeline.

Creating the GraphicsDevice

Although it is possible to create the graphics device yourself using the GraphicsDevice constructor, this is not needed when using Game class because the default template creates a GraphicsDeviceManager, which creates the GraphicsDevice.

If you want to change any of the default values that the GraphicsDeviceManager uses to create the graphics device, you can use code similar to the following in your Game class constructor.

public Game1()
{
// Create new graphics device manager that will create the graphics device
graphics = new GraphicsDeviceManager(this);
// Set the width and height we would like for the back buffer
graphics.PreferredBackBufferHeight = 800;
graphics.PreferredBackBufferWidth = 480;
// Set the back buffer format to color
graphics.PreferredBackBufferFormat = SurfaceFormat.Color;
// Set the depth format to have depth and stencil values
graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
// We don't want to use multisampling
graphics.PreferMultiSampling = false;

Content.RootDirectory = "Content";
}


The GraphicsDeviceManager.SupportedOrientations can be used to define which orientations you want your game to support. This is useful for Windows Phone games where the user can flip the physical phone device and might do so because of the requirements of the game. If you elect to support an orientation when the user rotates the phone, the screen flips to support the new orientation. For example, if you want to support a landscape game where the user can play the game by rotating the phone to the left or right, use the following lines of code:

graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft |
DisplayOrientation.LandscapeRight;

Now when the user rotates the phone from one horizontal position to the other, the display automatically flips and your game appears correctly for the new orientation.

Reference Devices

There is a special type of graphics device called a reference device also known as ref device. A reference device does not use the graphics hardware and implements all of the graphics functionally in software on the computer’s CPU. A reference device can be used when the graphics hardware does not support some specific graphics feature. The downside is that the reference device is tremendously slow compared to graphics hardware.

Drawing with Primitives

If you have never developed 3D graphics applications, this is where you become a graphics developer for the first time.

Primitive Types

XNA Game Studio supports four types of primitives defined by the PrimitiveType enumeration: TriangleList, TriangleStrip, LineList, and LineStrip. A TriangleList is a list of triangles just like its name implies. Every three vertices are treated as a new triangle meaning that each triangle requires three vertices to be stored. In most cases, this is overkill because most triangles are directly next to another triangle. With a TriangleStrip, the last three vertices are used to draw the next triangle. For example, you can draw two triangles with only four vertices. The first three vertices make up the first triangle and the last vertex is used in conjunction with the last two vertices from the first triangle to form the second triangle. Using triangle strips helps reduce the amount of memory required to store the vertices of triangles. The TriangleStrip is by far the most common PrimitiveType used.

The ListList is similar to the triangle list except that only two points are needed to form a single line. Every two points creates a new line segment. The LineStrip is similar to a triangle strip except that only the last point from the previous line segment is needed to form another line.

Vertex Types

Each vertex that makes up the triangle contains the position data for where the triangle is in space, but it can also contain other data such as the color that the triangle should be, texture coordinates for textured triangles, or normal data for lighting calculations. XNA Game Studio provides several ways to build in vertex types that can be used when defining your triangles or lines. You can also create your own vertex types for more complex rendering scenarios.

Drawing Primitives

There are ways to render geometric primitives in XNA Game Studio. All four methods are provided by the GraphicsDevice class. The first two methods—DrawUserPrimitives and DrawUserIndexedPrimitives—both work by specifying an array of vertices and a primitive type to the GraphicsDevice, which, in turn, draws the primitives.

The second two methods—DrawPrimitives and DrawIndexedPrimitives—use vertices that have been stored on the graphics hardware. Storing vertex data directly on the graphics hardware lowers drawing latency because the data needed to draw the geometry is already in memory in the graphics hardware near where the computations are occurring.

Along with vertex data, the two indexed methods—DrawUserIndexedPrimitives and DrawIndexedPrimitives—also use index values that are used to index into the vertex data. Instead of using the vertex data directly to draw the primitive, indexed vertices are defined using an offset into the vertex data. This saves space when multiple primitives use the same vertex.

DrawUserPrimitives

The easiest way to draw a primitive on the screen is to declare an array of vertices and pass these to the DrawUserPrimitive method. Along with the vertices, we create an instance of BasicEffect.

Define the following member variables in your Game class:

VertexPositionColor[] userPrimitives;
BasicEffect basicEffect;

Next, define the vertices and create a new instance of BasicEffect and set some of the properties. Add the following lines of code in your Game class LoadContent method:

// Create the verticies for our triangle
userPrimitives = new VertexPositionColor[3];
userPrimitives[0] = new VertexPositionColor();
userPrimitives[0].Position = new Vector3(0, 1, 0);
userPrimitives[0].Color = Color.Red;
userPrimitives[1] = new VertexPositionColor();
userPrimitives[1].Position = new Vector3(1, -1, 0);
userPrimitives[1].Color = Color.Green;
userPrimitives[2] = new VertexPositionColor();
userPrimitives[2].Position = new Vector3(-1, -1, 0);
userPrimitives[2].Color = Color.Blue;

// Create new basic effect and properites
basicEffect = new BasicEffect(GraphicsDevice);
basicEffect.World = Matrix.Identity;
basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 3),
new Vector3(0, 0, 0),
new Vector3(0, 1, 0));
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio,
0.1f, 100.0f);
basicEffect.VertexColorEnabled = true;


After you create your vertices, you create an instance of BasicEffect. The World, View, and Projection properties are used in the vertex shader portion of the graphics pipeline to transform the input vertices to draw on the screen. For now, don’t worry about the specific values for these matrices. The VertexColorEnabled property is set to true to tell the BasicEffect to use the color from each vertex as the output value of the pixel shader.

The final step is to issue the draw call using the DrawUserPrimitives method. Add the following lines of code to your Game class Draw method:

// Start using the BasicEffect
basicEffect.CurrentTechnique.Passes[0].Apply();
// Draw the primitives
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
userPrimitives, 0, 1);


Before you can call DrawUserPrimitives, tell the GraphicsDevice to use the BasicEffect. This is done by calling Apply on the EffectPass you use.

Next, call DrawUserPrimitives. This method is generic and expects the vertex type as the generic T type parameter. In this case, pass VertexPositionColor as the vertex type. The first parameter defines what PrimitiveType you want to draw. Specify TriangleList to draw a list of triangles. The second parameter is an array of vertices of the same type used for the generic T parameter. Pass the userPrimitives array you created previously. The third parameter is used to specify an offset into the array of vertices. If your array contains multiple primitive vertices and you want to draw only a subset of those, you can specify an offset into the source array. For your purpose, you don’t want any offset, so set the value to 0. The final parameter DrawUserPrimitives takes the total number of primitives to draw. If your array defines multiple primitives, specify that number to draw with this parameter. For this example, you draw only a single triangle, so specify a value of 1.

If you build and run the previous example, you should see a single triangle like that in Figure 1. Notice that each vertex has its own color. and the color of the middle sections of the triangle change across the triangle to each vertex. This is called interpolation and occurs on values that are specified per vertex. Because the color is specified per vertex, the different vertex colors have to interpolate over the pixels between the two vertices.

Figure 1. Using DrawUserPrimitives to draw a single triangle

Now let’s update the example to draw multiple primitives using the LineStrip primitive. First, update where the vertices are created with the following lines of code:

// Create the verticies for our lines
userPrimitives = new VertexPositionColor[4];
userPrimitives[0] = new VertexPositionColor();
userPrimitives[0].Position = new Vector3(-1, 1, 0);
userPrimitives[0].Color = Color.White;
userPrimitives[1] = new VertexPositionColor();
userPrimitives[1].Position = new Vector3(-1, -1, 0);
userPrimitives[1].Color = Color.White;
userPrimitives[2] = new VertexPositionColor();
userPrimitives[2].Position = new Vector3(1, 1, 0);
userPrimitives[2].Color = Color.White;
userPrimitives[3] = new VertexPositionColor();
userPrimitives[3].Position = new Vector3(1, -1, 0);
userPrimitives[3].Color = Color.White;

Note

The lines are set to Color.White to help make them more visible. You can use any color just like you would for triangles.


Then, update your DrawUserPrimitives call to specify the LineStrip primitive type and the new number of primitives:

// Draw the primitives
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip,
userPrimitives, 0, 3);


If you run the example now, it should look like Figure 2.

Figure 2. Using DrawUserPrimitives to draw a LineStrip

DrawUserIndexedPrimitives

If your primitives commonly use the same vertices for a number of different primitives, it can save you memory to use indexed primitives instead. To draw a user indexed primitive, you need to specify an array of indexes to use when drawing the triangles. These index values are used to look up each specific vertex to use when rendering the primitive.

To draw a user indexed primitive, update the current example. Add an array of index value. These are integer values that represent offsets into the vertex array you also pass into the DrawUserIndexedPrimitives method. Update the member variables for your Game class to have the additional index array like the following code:

VertexPositionColor[] userPrimitives;
short[] userPrimitivesIndices;
BasicEffect basicEffect;

Use a 16-bit short array to store the index values. Because each index is represented by a short, the index values can be between only 0 and 65535, which is the maximum positive number a short can represent. You can also use an array of 32-bit int values, which can store positive values of more than four billion but this has two repercussions. The first is that storing index values as int values means that each index takes up two more bytes than when using shorts thus doubling the memory usage for your index values. The other is that 32-bit int indexes are supported only in the HiDef GraphicsProfile, so your game must usea HiDef GraphicsDevice.

Next, create the vertices and index values for your primitives. In this case, draw a square, often called a quad, that is made of two triangles. Update the existing example’s LoadContent method to contain the following code:

// Create the verticies for our triangle
userPrimitives = new VertexPositionColor[4];
userPrimitives[0] = new VertexPositionColor();
userPrimitives[0].Position = new Vector3(-1, 1, 0);
userPrimitives[0].Color = Color.Red;
userPrimitives[1] = new VertexPositionColor();
userPrimitives[1].Position = new Vector3(1, 1, 0);
userPrimitives[1].Color = Color.Green;
userPrimitives[2] = new VertexPositionColor();
userPrimitives[2].Position = new Vector3(-1, -1, 0);
userPrimitives[2].Color = Color.Blue;
userPrimitives[3] = new VertexPositionColor();
userPrimitives[3].Position = new Vector3(1, -1, 0);
userPrimitives[3].Color = Color.Purple;

// Create the indices used for each triangle
userPrimitivesIndices = new short[6];
// First Triangle
userPrimitivesIndices[0] = 0;
userPrimitivesIndices[1] = 1;
userPrimitivesIndices[2] = 2;
// Second Trianglel
userPrimitivesIndices[3] = 1;
userPrimitivesIndices[4] = 3;
userPrimitivesIndices[5] = 2;


Like the previous example, create an array of VertexPositionColor to represent the vertices in your primitives. The code creates four vertices: one for each corner of the quad. A short array is then created to specify which vertex to use for each primitive. The first triangle uses the top left, top right, and bottom left vertices making sure to define them in clockwise order. The second triangle uses the top right, bottom right, and bottom left.

Finally, update your Game class Draw method to use the DrawUserIndexPrimitives method:

// Draw the primitives
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
userPrimitives, 0, 4,
userPrimitivesIndices, 0, 2);


Like the previous example with DrawUserPrimitives, the DrawUserIndexedPrimitives call is generic and you pass the VertexPositionColor as the generic T type parameter. The first parameter is again the primitive type. The second parameter is again the array of vertices. The third parameter is the vertex offset that should be used. For index primitives, this offset is added to each index value to obtain the final index to use in the vertex array. The fourth parameter is the number of vertices that is used in the draw call. In this case, use four vertices. This parameter is often the size of the vertex array itself unless you use offsets. The fifth parameter is the array used to store the index values. For the example, that is the userPrimitivesIndices variable. The sixth parameter is the offset into the index array that should be used. In this case, you don’t need to offset, so the value is 0. The final parameter is again the number of primitives to draw. For the example, you try two triangles, so a value of 2 is specified.

If you build and run the example code, you should see an image like that in Figure 3 where a four-color quad is draw on the screen.

Figure 3. Using DrawUserIndexedPrimitives to draw a quad

Let’s lower the memory used by the index array by updating the example to just use four index values and use the TriangleStrip PrimitiveType. Update where you create the index array to look like the following:

// Create the indices used for each triangle
userPrimitivesIndices = new short[6];
// First triangle
userPrimitivesIndices[0] = 0;
userPrimitivesIndices[1] = 1;
userPrimitivesIndices[2] = 2;
// Second Triangle
userPrimitivesIndices[3] = 3;

The second triangle is formed by using the last two index values plus the new additional value. In this case, the triangle is formed by userPrimitivesIndices[3], userPrimitivesIndices[2], and userPrimitivesIndices[1]. This second triangle saves 32 bits of data by not using two additional index values.

The DrawUserIndexedPrimitives method call needs to be updated to use only PrimitiveType.TriangleStrip and not TriangleList. If you run the example code now, you will not see any visible difference yet you are saving valuable memory space. It is not always possible to save space and use triangle strips; in these cases, you should use TriangleLists.

DrawPrimitives

Unlike the user versions of the draw primitives methods that use arrays to store the vertex data, DrawPrimitive uses a VertexBuffer to store the vertices for your primitives.

A VertexBuffer stores the vertices in the graphics cards hardware memory where they can be quickly accessed. Unlike when using arrays, a VertexBuffer does not require the vertices to be sent from the main system memory to the graphics card each time you want to draw. Sending large amounts of data from the main system memory to the graphics card is not a fast operation and can slow down your rendering speed. So for larger geometry, use a VertexBuffer to store the vertex data and to call the DrawPrimitives method.

First, create two member variables in your Game class: one for the VertexBuffer and another for the BasicEffect. Add the following lines of code to create the member variables:

VertexBuffer vertexBuffer;
BasicEffect basicEffect;

Next, create the VertexBuffer and set the data that is stored inside it. Add the following lines of code to your Game class LoadContent method:

basicEffect = new BasicEffect(GraphicsDevice);
basicEffect.World = Matrix.Identity;
basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 3),
new Vector3(0, 0, 0),
new Vector3(0, 1, 0));
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio,
0.1f, 100.0f);
basicEffect.VertexColorEnabled = true;

VertexPositionColor[] vertexData = new VertexPositionColor[3];
vertexData[0] = new VertexPositionColor();
vertexData[0].Position = new Vector3(0, 1, 0);
vertexData[0].Color = Color.Red;
vertexData[1] = new VertexPositionColor();
vertexData[1].Position = new Vector3(1, -1, 0);
vertexData[1].Color = Color.Green;
vertexData[2] = new VertexPositionColor();
vertexData[2].Position = new Vector3(-1, -1, 0);
vertexData[2].Color = Color.Blue;

// Create our VertexBuffer
vertexBuffer = new VertexBuffer(GraphicsDevice,
typeof(VertexPositionColor), 3,
BufferUsage.None);
vertexBuffer.SetData<VertexPositionColor>(vertexData);


As with the previous example, you first create an instance of BasicEffect and set some of the properties for the transforms and enable vertex coloring.

Again, declare an array of VertexPositionColor and define three vertices. Use this array to set the data to store in the VertexBuffer.

Next, create the instance of the VertexBuffer. The VertexBuffer takes the GraphicsDevice to store the data as the first parameter. Use the GraphicsDevice property of the Game class to use the default GraphicsDevice that is created when your game starts. The second parameter takes the Type of the vertex that is to be stored in the VertexBuffer. Because you want to store vertices of type VertexPositionColor, specify the type using the typeof operator. The third parameter is the number of vertices the VertexBuffer is going to hold. In this case, there are only three vertices. The fourth and final parameter is the BufferUsage. In cases where you know you will never need to read the contents of the VertexBuffer, you can specify BufferUsage.WriteOnly, which causes the VertexBuffer to throw an exception if you ever try to read back any data. Using WriteOnly enables the graphics hardware to chose specific memory locations in the hardware that allow for more efficient drawing.

After the VertexBuffer is created, the SetData method is called to send the vertex data to the graphics hardware. SetData is a generic method that takes the type of vertex data as the generic T parameter. The array of vertices is then passed as the lone parameter. The size of the VertexBuffer must be large enough to store the amount of vertices stored in the array that is passed in. Overloaded versions of SetData are available that enable you to specify an offset, start index, number of vertices to set, and the size of each vertex. These overloads are useful when the source vertex array is slit into multiple vertex buffers.

The final steps you need to draw are to tell the GraphicsDevice the VertexBuffer you plan to use next and to call the DrawPrimitives method. Add the following lines of code to your Game class Draw method:

// Set which vertex buffer to use
GraphicsDevice.SetVertexBuffer(vertexBuffer);
// Set which effect to use
basicEffect.CurrentTechnique.Passes[0].Apply();
// Draw the triangle using the vertex buffer
GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

The GraphicsDevice is told which VertexBuffer to use by calling the SetVertexBuffer method and passing in the one you created. This is the VertexBuffer that is used when any DrawPrimitives or DrawIndexPrimitives methods are called until another VertexBuffer is set on the GraphicsDevice. Overloads of SetVertexBuffer are available that enable an offset into the VertexBuffer to be specified.

Next, the EffectPass.Apply method is called like in the previous example.

Finally, call the DrawPrimitives method. The first parameter is the PrimitiveType. The second parameter is the start vertex. This is the vertex in the buffer to start drawing from. This value is combined with any offset value set when SetVertexBuffer is called. The final parameter is the number of primitives to draw, which you set to 1 because you need to draw only the single triangle.

If you run the previous example code, you see output similar to Figure 4. Notice how this example and the first example that used DrawUserPrimitives produced the same results but use different functions to draw the primitives.

Figure 4. Using DrawPrimitives to draw a triangle

DrawIndexedPrimitives

The final draw primitives called DrawIndexedPrimitives uses both a VertexBuffer and an IndexBuffer. Like a VertexBuffer, the IndexBuffer stores data using the graphics hardware’s memory so it can be quickly accessed by the GPU when drawing. The IndexBuffer stores index values like the ones you used previously when using the DrawUserIndexPrimitives method.

To draw indexed primitives using an index buffer, add a member variable to your Game class to hold the instances of the IndexBuffer, VertexBuffer, and BasicEffect.

VertexBuffer vertexBuffer;
IndexBuffer indexBuffer;
BasicEffect basicEffect;

Next, create the index data to store in the IndexBuffer and create the instance of the IndexBuffer. Also create the VertexBuffer and BasicEffect as you did previously:

basicEffect = new BasicEffect(GraphicsDevice);
basicEffect.World = Matrix.Identity;
basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 3),
new Vector3(0, 0, 0),
new Vector3(0, 1, 0));
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio,
0.1f, 100.0f);
basicEffect.VertexColorEnabled = true;

VertexPositionColor[] vertexData = new VertexPositionColor[4];
vertexData[0] = new VertexPositionColor();
vertexData[0].Position = new Vector3(-1, 1, 0);
vertexData[0].Color = Color.Red;
vertexData[1] = new VertexPositionColor();
vertexData[1].Position = new Vector3(1, 1, 0);
vertexData[1].Color = Color.Green;
vertexData[2] = new VertexPositionColor();
vertexData[2].Position = new Vector3(-1, -1, 0);
vertexData[2].Color = Color.Blue;
vertexData[3] = new VertexPositionColor();
vertexData[3].Position = new Vector3(1, -1, 0);
vertexData[3].Color = Color.Purple;

// Create our VertexBuffer
vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor),
4, BufferUsage.None);
vertexBuffer.SetData<VertexPositionColor>(vertexData);

short[] indexData = new short[4];
// First triangle
indexData[0] = 0;
indexData[1] = 1;
indexData[2] = 2;
// Second triangle
indexData[3] = 3;

// Create our IndexBuffer
indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits,
4, BufferUsage.None);
indexBuffer.SetData<short>(indexData);


In the previous code, you create an array of shorts to store the index values. Because you use a triangle strip, you need only four index values. The IndexBuffer is then created. The first parameter is the GraphicsDevice where the IndexBuffer is stored. The second parameter is the size each element in the index buffer is. Remember that index values can be 16-bit short values or 32-bit int values. You select IndexElementSize.SixteenBits to specify that 16-bit index values. The fourth parameter is the number of index values the IndexBuffer holds. You specify 4 the size of your index data array. The last parameter is BufferUsage, which is similar to the same parameter on the VertexBuffer. You specify None, which will enables read back if necessary later.

Finally, tell the GraphicsDevice which IndexBuffer to use when the DrawIndexPrimitives method is called. Add the following lines of code to your Game class Draw method:

// Set which vertex buffer to use
GraphicsDevice.SetVertexBuffer(vertexBuffer);
// Set which index buffer to use
GraphicsDevice.Indices = indexBuffer;
// Set which effect to use
basicEffect.CurrentTechnique.Passes[0].Apply();
// Draw the triangle using the vertex buffer and index buffer
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, 4, 0, 2);


As with the previous examples, you set the VertexBuffer to use and call Apply on the EffectPass you want to use. You also specify the Indices parameter of the GraphicsDevice setting its value to your IndexBuffer. The DrawIndexedPrimitives method is then called to draw a quad on the screen. Like all of the other draw methods, the first parameter is the PrimitveType, which, in this case, is a TriangleStrip. The second parameter is the base vertex, which is an offset that is added to each of the values in the index buffer. The third parameter is the minimum vertex index of all of the vertices used. The fourth parameter is the number of vertices that are going to be used when drawing the triangles. The fifth parameter is the starting index to use in the index buffer. The last parameter like the other draw methods is the number of primitives to draw.

If you run the example code, you should see a colored quad similar to the one in Figure 5.

Figure 5. Using DrawIndexedPrimitives to draw a quad
Other -----------------
- Developing for Windows Phone and Xbox Live : Reach and HiDef Graphics Profiles
- Developing for Windows Phone and Xbox Live : Graphics Pipeline
- Developing for Windows Phone and Xbox Live : Graphics Pipeline
- Programming Windows Phone 7 : Elements and Properties - More on Images
- Programming Windows Phone 7 : TextBlock Properties and Inlines
- Programming Windows Phone 7 : The Phone’s Photo Library
- Programming Windows Phone 7 : Capturing from the Camera
- Windows Phone 7 : Loading Local Bitmaps from Code
- Windows Phone 7 : Image and ImageSource
- Windows Phone 7 : Images Via the Web
- Windows Phone 7 : Customizing Your E-Mail Signature
- Windows Phone 7 : Managing Mail Folders
- Windows Phone 7: The Silverlight Image Element
- Windows Phone 7: XNA Texture Drawing
- Windows Phone 7: An Introduction to Touch - Routed Events
- Windows Phone 7 : Working with Attachments
- Programming Windows Phone 7: An Introduction to Touch - The Manipulation Events
- Programming Windows Phone 7: An Introduction to Touch - Low-Level Touch Events in Silverlight
- Windows Phone 7: Composing a New Message
- Programming Windows Phone 7: An Introduction to Touch - The XNA Gesture Interface
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us